#include "sci_handle.h"
#include "mlog.h"

/*支持最大通讯接口数*/
#define MAX_COM_NUM 3

typedef enum {
    RX_IDLE,
    RX_READY,
    RX_FINISH,
} ReceiveSatus;

typedef struct {
    /*缓冲索引*/
    uint8_t BufIndex;
    /*缓存指针，指向存储数据的数组*/
    uint8_t* DataBuf;
    /*接收状态标志位*/
    ReceiveSatus DataFlag;
    /*缓冲区大小*/
    uint16_t DataBufSize;
    /*已接收数据长度*/
    uint16_t DataLen;
    /*设置接收超时时间*/
    uint16_t DataReceiveTimeout;
    /*数据处理函数*/
    DataHandleFunc DataHandle;
    /*数据接收计时*/
    TICK Timer;
} CommDataBuf;

CommDataBuf cDataBuf[MAX_COM_NUM];

void Comm_DataBufInit(void)
{
    uint8_t i = 0;
    for (i = 0; i < MAX_COM_NUM; i++) {
        cDataBuf[i].BufIndex = i;
        cDataBuf[i].DataBuf = NULL;
        cDataBuf[i].DataFlag = RX_IDLE;
        cDataBuf[i].DataLen = 0;
        cDataBuf[i].DataHandle = NULL;
        cDataBuf[i].DataReceiveTimeout = 0;
    }
}
uint8_t DataBufInit(uint8_t* buf, uint16_t buf_size, DataHandleFunc handle,
                    uint16_t timeout)
{
    uint8_t i = 0;
    if (buf == NULL) {
        return 0xff;
    }
    for (i = 0; i < MAX_COM_NUM; i++) {
        if (cDataBuf[i].DataBuf == NULL) {
            cDataBuf[i].DataBuf = buf;
            cDataBuf[i].DataLen = 0;
            cDataBuf[i].DataBufSize = buf_size;
            cDataBuf[i].DataHandle = handle;
            cDataBuf[i].DataReceiveTimeout = timeout;
            return i;
        }
    }
    return 0xff;
}

uint8_t Comm_DataBlockProcess(uint8_t uartIndex, uint32_t blockTime,
                              DataHandleFunc func)
{
    uint32_t time = 0;
    uint8_t ret = 0;

    time = getSystemTime();

    while ((getSystemTime() - time) < blockTime) {
        // iwdg_Feed();
        if (cDataBuf[uartIndex].DataBuf != NULL) {
            if (cDataBuf[uartIndex].DataHandle != NULL) {
                if (cDataBuf[uartIndex].DataFlag == RX_FINISH) {
                    ret = func(cDataBuf[uartIndex].DataBuf,
                               cDataBuf[uartIndex].DataLen);
                    cDataBuf[uartIndex].DataFlag = RX_IDLE;
                    cDataBuf[uartIndex].DataLen = 0;
                    return ret;
                }
            }
        }
    }
    return 0;
}

void Comm_DataReceiveCheck(void)
{
    uint8_t i = 0;
    for (i = 0; i < MAX_COM_NUM; i++) {
        if (cDataBuf[i].DataBuf != NULL) {
            if (cDataBuf[i].DataFlag == RX_FINISH) continue;
            if (cDataBuf[i].DataLen <= 0) continue;
            GET_TICK(cDataBuf[i].Timer.tick_temp);
            if ((cDataBuf[i].Timer.tick_temp - cDataBuf[i].Timer.tick_begin) >
                cDataBuf[i].DataReceiveTimeout) {
                cDataBuf[i].DataFlag = RX_FINISH;
            }
        }
    }
}
void Comm_DataReceive(uint8_t bufIndex, uint8_t data)
{
    if (cDataBuf[bufIndex].DataBuf == NULL) {
        mprintf(LOG_ERROR, "no malloc spsace.\r\n");
        return;
    }
    if (cDataBuf[bufIndex].DataFlag == 1) {
        mprintf(LOG_ERROR, "receive data no process.\r\n");
        return;
    }
    if (cDataBuf[bufIndex].DataLen > cDataBuf[bufIndex].DataBufSize) {
        mprintf(LOG_ERROR, "data overflow\r\n");
        cDataBuf[bufIndex].DataLen = 0;
        return;
    }

    cDataBuf[bufIndex].DataBuf[cDataBuf[bufIndex].DataLen++] = data;
    GET_TICK(cDataBuf[bufIndex].Timer.tick_begin);
}

void Comm_DataHandle(void)
{
    uint8_t i = 0;
    for (i = 0; i < MAX_COM_NUM; i++) {
        if (cDataBuf[i].DataBuf != NULL) {
            if (cDataBuf[i].DataHandle != NULL) {
                if (cDataBuf[i].DataFlag == RX_FINISH) {
                    cDataBuf[i].DataHandle(cDataBuf[i].DataBuf,
                                           cDataBuf[i].DataLen);
                    cDataBuf[i].DataFlag = RX_IDLE;
                    cDataBuf[i].DataLen = 0;
                }
            }
        }
    }
}
